<script setup>
import { Handle, useHandleConnections, useVueFlow } from '@vue-flow/core';
import { NodeToolbar } from '@vue-flow/node-toolbar';
import { defineEmits, reactive, toRef } from 'vue';
import { VsLoadingFn } from 'vuesax-alpha';
import { initCommonNodeProp, initNodePropByType } from '../../drag/initProp';
import { initEdges } from '../../edge/initEdgeProp';
import NodeIcon from '../../icon/NodeIcon.vue';

const props = defineProps({
  id: {
    type: String,
    required: true,
  },
  data: {
    type: Object,
    required: true,
  },
  sourcePosition: {
    type: String,
  },
  targetPosition: {
    type: String,
  },
})

function uuid() {
  return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    var r = Math.random() * 16 | 0,
        v = c == 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}

const emit = defineEmits(['layoutGraph'])

const { addNodes, addEdges, removeNodes, findNode, updateNodeData } = useVueFlow()
const node = findNode(props.id)
const dataRef = ref(props.data)
const id = ref(props.data.id || '')
const name = ref(props.data.name || '')
const nodeDataBase = reactive(props.data.nodeDataBase || {})
const nodeDataLoop = reactive(props.data.nodeDataLoop || {})
const style = reactive(props.data.style || {})

watch(id, val => {  
  node.data.id = val;
})

watch(name, val => {  
  node.data.name = val;
})

watchEffect(() => {
  node.data.nodeDataBase = nodeDataBase
  node.data.nodeDataLoop = nodeDataLoop
  node.data.style = style
});

const sourceConnections = useHandleConnections({
  type: 'target',
})

const targetConnections = useHandleConnections({
  type: 'source',
})

const isSender = toRef(() => sourceConnections.value.length <= 0)

const isReceiver = toRef(() => targetConnections.value.length <= 0)

const bgColor = toRef(() => {
  if (isSender.value) {
    if (props.data.hasError) {
      return '#f87171'
    }
    if (props.data.isFinished) {
      return '#42B983'
    }
    if (props.data.isCancelled) {
      if (loadingInstance) {
        loadingInstance?.close();
        loadingInstance = null; // 关闭后清空实例
      }
      return '#fbbf24'
    }
    return '#ddd'
  }

  if (props.data.hasError) {
    return '#f87171'
  }

  if (props.data.isFinished) {
    return '#42B983'
  }

  if (props.data.isCancelled) {
    return '#fbbf24'
  }

  return '#ddd'
})

const dialogStyleActive = ref(false)
const counterDanger = ref(false)
const nodeRef = ref(null)

const handleOpacity = computed(() => {
  return style.handles.map(handle => handle.opacity > 0);
});

const setHandleOpacity = (index, value) => {
  style.handles[index].opacity = value ? 1 : 0;
};

const handleOpacityExtend = computed(() => {
  return style.extendHandles.map(handle => handle.opacity > 0);
});

const setHandleOpacityExtend = (index, value) => {
  style.extendHandles[index].opacity = value ? 1 : 0;
};

const handleStyle = ref();
const handleStyleText = ref()
const dialogStyleClick = (handle) => {
  dialogStyleActive.value = true;
  handleStyleText.value = handle.style;
  handleStyle.value = handle;
};

watch(handleStyleText, val => {  
  handleStyle.value.style = val;
  nextTick(() => {
    updateNodeInternals([props.id]);
  });
})

const modeDefault = ref(true)
let loadingInstance = null; 
// 直接使用 props.data，因为 props 本身是响应式的
onMounted(() => {
  watch(() => props.data.isRunning, (newVal, oldVal) => {
    if (newVal) {
      if(modeDefault.value){
        loadingInstance = VsLoadingFn({
          target: nodeRef,
          text: 'Loading...',
        });
      }else{
        loadingInstance = VsLoadingFn({
          target: nodeRef,
        });
      }
    } else {
      if (loadingInstance) {
        loadingInstance?.close();
        loadingInstance = null; // 关闭后清空实例
      }
    }
  }, { immediate: true }); // immediate: true 选项可以在初次绑定时立即执行一次回调

  watch(() => node.data.type, (newVal, oldVal) => {
    node.data = initNodePropByType(newVal)
    if(newVal == 'switch_script' || newVal == 'if_script' || newVal == 'boolean_script' || newVal == 'while_script' || newVal == 'for_script' || newVal == 'iterator_script'){
      node.type = 'script'
    }else{
      node.type = newVal
    }
  })

  watch(() => props.data, (newVal, oldVal) => {
    if (newVal.mode == 'default') {
      modeDefault.value = true
    } else {
      modeDefault.value = false
    }
    id.value = newVal.id
    name.value = newVal.name
  }, { immediate: true, deep: true }); 

  if(id.value == ''){
    id.value = uuid();
  }
  
  initCmpList()
});

const cmpOptions = ref({})
const initCmpList = async () => {
  const res = await $ivyApi.post('/liteflow/parser/cmpOptions', {type: node.data.type})
  cmpOptions.value = res.data;
}

const addLeftPoint = () => {
  style.extendHandles.push(...[{id: uuid(), position: 'left', opacity: 1, type: 'source', style: 'top:10px;left:0px;'}])
};

const addRightPoint = () => {
  style.extendHandles.push(...[{id: uuid(), position: 'right', opacity: 1, type: 'source', style: 'top:10px;right:0px;'}])
};

const addTopPoint = () => {
  style.extendHandles.push(...[{id: uuid(), position: 'top', opacity: 1, type: 'source', style: 'top:0px;left:10px;'}])
};

const addBottomPoint = () => {
  style.extendHandles.push(...[{id: uuid(), position: 'bottom', opacity: 1, type: 'source', style: 'bottom:0px;left:10px'}])
};


//编辑器
const popupDataJson = ref(false)
const options = ref({
  colorDecorators: true,
  lineHeight: 24,
  tabSize: 2,
})

// Toolbar
const addParentNodeClick = () => {
  const node = findNode(props.id)
  const nodeData = JSON.parse(JSON.stringify(node));
  const uid = uuid();
  nodeData.data.id = uid;

  const newNode = {
    id: uid,
    type: nodeData.type,
    position: {
      x: nodeData.position.x - 450,
      y: nodeData.position.y
    },
    label: nodeData.label,
    data: nodeData.data
  }
  addNodes([newNode])
  addEdges(initEdges(newNode.id, nodeData.id))
  emit('layoutGraph', 'LR')
}

const addChildNodeClick = () => {
  const node = findNode(props.id)
  const nodeData = JSON.parse(JSON.stringify(node));
  const uid = uuid();
  nodeData.data.id = uid;

  const newNode = {
    id: uid,
    type: nodeData.type,
    position: {
      x: nodeData.position.x + 450,
      y: nodeData.position.y
    },
    label: nodeData.label,
    data: nodeData.data
  }
  addNodes([newNode])
  addEdges(initEdges(nodeData.id, newNode.id))
  emit('layoutGraph', 'LR')
}

const copyNodeClick = () => {
  const node = findNode(props.id)
  const nodeData = JSON.parse(JSON.stringify(node));
  const uid = uuid();
  nodeData.data.id = uid;
  const newNode = {
    id: uid,
    type: nodeData.type,
    position: {
      x: nodeData.position.x,
      y: nodeData.position.y + 300
    },
    label: nodeData.label,
    data: nodeData.data
  }

  nextTick(() => {
    addNodes([newNode])
  })
}

const resetNodePropClick = () => {
  const json = initCommonNodeProp();
  id.value = uuid()
  name.value = json.name
  Object.keys(nodeDataBase).forEach(key => {
    delete nodeDataBase[key]; // 删除所有属性
  });
  Object.keys(nodeDataLoop).forEach(key => {
    delete nodeDataLoop[key]; // 删除所有属性
  });
}

const resetNodeStyleClick = () => {
  const json = initCommonNodeProp();
  style.handles = []
  nextTick(() => {
    style.handles = json.style.handles
    style.extendHandles = json.style.extendHandles
  })
}

const removeNodeClick = () => {
  removeNodes(props.id)
}

//代码编辑器
const popupDataCode = ref(false)
const codeLanguage = ref('java')
const codeOptions = ref({
  colorDecorators: true,
  lineHeight: 24,
  tabSize: 2,
})
const onPopupDataCode = () => {
  popupDataCode.value = true
  if(nodeDataBase.language == 'groovy'){
    codeLanguage.value = 'groovy'
  }else if(nodeDataBase.language == 'qlexpress'){
    codeLanguage.value = 'text'
  }else if(nodeDataBase.language == 'js'){
    codeLanguage.value = 'js'
  }else if(nodeDataBase.language == 'python'){
    codeLanguage.value = 'python'
  }else if(nodeDataBase.language == 'lua'){
    codeLanguage.value = 'lua'
  }else if(nodeDataBase.language == 'java'){
    codeLanguage.value = 'java'
  }else if(nodeDataBase.language == 'kotlin'){
    codeLanguage.value = 'kotlin'
  }else{
    codeLanguage.value = 'text'
  }
}
</script>

<template>
  <div ref="nodeRef" class="process-node" :style="{ 'inline-size': modeDefault ? '300px' : '180px', borderWidth: '1px', borderColor: bgColor}">
    <NodeToolbar :is-visible="dataRef.style.toolbar.isVisible" :position="dataRef.style.toolbar.position" :offset="dataRef.style.toolbar.offset">
      <vs-tooltip placement="top">
        <vs-button color="#195bff" shape="circle" icon type="floating" @click="addParentNodeClick">
          <vs-icon v-if="dataRef.style.toolbar.showIcon" size="30">
            <vs-icon-plus />
          </vs-icon>
        </vs-button>
        <template #content> 插入父节点 </template>
      </vs-tooltip>
      
      <vs-tooltip placement="top">
        <vs-button shape="circle" icon type="floating" @click="addChildNodeClick">
          <vs-icon v-if="dataRef.style.toolbar.showIcon" size="30">
            <vs-icon-plus />
          </vs-icon>
        </vs-button>
        <template #content> 插入子节点 </template>
      </vs-tooltip>

      <vs-tooltip placement="top">
        <vs-button color="whatsapp" shape="circle" icon type="floating" @click="copyNodeClick">
          <vs-icon v-if="dataRef.style.toolbar.showIcon" size="30">
            <vs-icon-Pause />
          </vs-icon>
        </vs-button>
        <template #content> 复制节点 </template>
      </vs-tooltip>
      
      <vs-tooltip placement="top">
        <vs-button color="#ff8200" shape="circle" icon type="floating" @click="resetNodePropClick">
          <vs-icon v-if="dataRef.style.toolbar.showIcon" size="30">
            <vs-icon-trash />
          </vs-icon>
        </vs-button>
        <template #content> 重置属性 </template>
      </vs-tooltip>
      
      <vs-tooltip placement="top">
        <vs-button color="#ff8200" shape="circle" icon type="floating" @click="resetNodeStyleClick">
          <vs-icon v-if="dataRef.style.toolbar.showIcon" size="30">
            <vs-icon-trash />
          </vs-icon>
        </vs-button>
        <template #content> 重置样式 </template>
      </vs-tooltip>
      
      <vs-tooltip placement="top">
        <vs-button color="#ff3e4e" shape="circle" icon type="floating" @click="removeNodeClick">
          <vs-icon v-if="dataRef.style.toolbar.showIcon" size="30">
            <vs-icon-trash />
          </vs-icon>
        </vs-button>
        <template #content> 删除节点 </template>
      </vs-tooltip>
      
    </NodeToolbar>
    
    <VsRow>
      <VsCol class="process-node-title" :sm="12">
        <NodeIcon :name="dataRef.type" :text="name" />
      </VsCol>
    </VsRow>

    <VsCollapse v-if="modeDefault" type="margin" class="ivy-collapse-height" style="padding-block: 0;padding-inline: 10px;">
      <VsCollapseItem class="ivy-node-collapse">
        <template #header>
          <div>
            属性配置
          </div>
        </template>
        <vs-input
          v-model="id"
          class="w-100 nodrag"
          color="success" 
          label="组件ID" 
          label-float 
        />

        <vs-input
          v-model="name"
          class="w-100 nodrag"
          color="success" 
          label="组件名称" 
          label-float 
        />

        <vs-select
          v-model="node.data.type"
          class="w-100 nodrag"
          filter
          label="组件类型"
          color="success"  
          label-float
        >
          <vs-option-group label="组件">
            <vs-option label="普通组件" value="common"> 普通组件 </vs-option>
            <vs-option label="选择组件" value="switch"> 选择组件 </vs-option>
            <vs-option label="条件组件" value="if"> 条件组件 </vs-option>
            <vs-option label="布尔组件" value="boolean"> 布尔组件 </vs-option>
            <vs-option label="循环条件组件" value="while"> 循环条件组件 </vs-option>
            <vs-option label="循环次数组件" value="for"> 循环次数组件 </vs-option>
            <vs-option label="循环迭代组件" value="iterator"> 循环迭代组件 </vs-option>
          </vs-option-group>
          <vs-option-group label="脚本">
            <vs-option label="普通脚本组件" value="script"> 普通脚本组件 </vs-option>
            <vs-option label="选择脚本组件" value="switch_script"> 选择脚本组件 </vs-option>
            <vs-option label="条件脚本组件" value="if_script"> 条件脚本组件 </vs-option>
            <vs-option label="布尔脚本组件" value="boolean_script"> 布尔脚本组件 </vs-option>
            <vs-option label="循环条件脚本组件" value="while_script"> 循环条件脚本组件 </vs-option>
            <vs-option label="循环次数脚本组件" value="for_script"> 循环次数脚本组件 </vs-option>
            <vs-option label="循环迭代脚本组件" value="iterator_script"> 循环迭代脚本组件 </vs-option>
          </vs-option-group>
        </vs-select>

        <div style="block-size: 20px;margin-block: 10px 10px;">
          <vs-radio v-model="nodeDataBase.classType" :value="0" style="float: inline-start;"> 普通类 </vs-radio>
          <vs-radio v-model="nodeDataBase.classType" :value="1" style="float: inline-start;"> BEAN </vs-radio>
          <vs-radio v-model="nodeDataBase.classType" :value="2" style="float: inline-start;"> 动态类 </vs-radio>
          <vs-radio v-model="nodeDataBase.classType" :value="3" style="float: inline-start;"> 脚本 </vs-radio>
        </div>

        <vs-select
          v-if="nodeDataBase.classType == 0 || nodeDataBase.classType == 1"
          v-model="nodeDataBase.clazz"
          class="w-100 nodrag"
          filter
          flip	
          teleported	
          allow-create
          label="组件类"
          color="success"  
          label-float
        >
          <vs-option v-if="nodeDataBase.classType == 0" v-for="(item,index) in cmpOptions.c0" :key="'c0_'+index" :label="item" :value="item"></vs-option>
          <vs-option v-else v-for="(item,index) in cmpOptions.c1" :key="'c1_'+index" :label="item" :value="item"></vs-option>
        </vs-select>

        <vs-select
          v-if="nodeDataBase.classType == 3"
          v-model="nodeDataBase.language"
          class="w-100 nodrag"
          filter
          label="脚本语言"
          color="success"  
          label-float
        >
          <vs-option label="java" value="java"> java </vs-option>
          <vs-option label="custom" value="custom"> custom </vs-option>
          <vs-option label="groovy" value="groovy"> groovy </vs-option>
          <vs-option label="qlexpress" value="qlexpress"> qlexpress </vs-option>
          <vs-option label="js" value="js"> js </vs-option>
          <vs-option label="python" value="python"> python </vs-option>
          <vs-option label="lua" value="lua"> lua </vs-option>
          <vs-option label="aviator" value="aviator"> aviator </vs-option>
          <vs-option label="kotlin" value="kotlin"> kotlin </vs-option>
        </vs-select>

        <vs-button v-if="nodeDataBase.classType == 2 || nodeDataBase.classType == 3" size="small" @click="onPopupDataCode" style="inline-size: 100%;margin-block-start: 12px;">
          {{nodeDataBase.classType == 2 ? '动态类' : '脚本'}}代码编辑器
        </vs-button>

        <vs-dialog v-model="popupDataCode"  not-close auto-width>
          <template #header>
            <h3>{{nodeDataBase.classType == 2 ? '动态类' : '脚本'}}代码{{nodeDataBase.classType == 3 && nodeDataBase.language ? '('+nodeDataBase.language+')': ''}}</h3>
          </template>
          <div class="con-content-scroll">
            <MonacoEditor
              theme="vs"
              :options="codeOptions"
              :language="codeLanguage"
              :width="700"
              :height="500"
              v-model:value="nodeDataBase.code"
            />
          </div>
        </vs-dialog>

        <vs-input
          v-model="nodeDataBase.id"
          class="w-100 nodrag"
          color="success" 
          label="表达式ID" 
          label-float 
        />

        <vs-input
          v-model="nodeDataBase.tag"
          class="w-100 nodrag"
          color="success" 
          label="组件标签" 
          label-float 
        />

        <vs-input
          v-model="nodeDataBase.maxWaitSeconds"
          class="w-100 nodrag"
          color="success" 
          label="最大等待时间(秒)" 
          label-float 
        />

        <vs-checkbox v-model="nodeDataLoop.parallel"> 开启异步循环 </vs-checkbox>
        
        <vs-input
          v-model="nodeDataLoop.loopNumber"
          class="w-100 nodrag"
          color="success" 
          label="循环次数" 
          label-float 
        />

        <vs-input
          v-model="nodeDataBase.retryCount"
          class="w-100 nodrag"
          color="success" 
          label="重试次数" 
          label-float 
        />

        <vs-select
          v-model="nodeDataBase.retryExceptions"
          class="w-100 nodrag"
          filter
          allow-create
          multiple
          :multiple-limit="4"
          collapse-chips
          :max-collapse-chips="2"
          label="指定异常的重试(可创建选项)"
          color="success"  
          label-float
        >
          <vs-option-group label="RuntimeException类">
            <vs-option label="NullPointerException[空指针异常]" value="java.lang.NullPointerException"> NullPointerException[空指针异常] </vs-option>
            <vs-option label="ArrayIndexOutOfBoundsException[数组索引越界异常]" value="java.lang.ArrayIndexOutOfBoundsException"> ArrayIndexOutOfBoundsException[数组索引越界异常] </vs-option>
            <vs-option label="IllegalArgumentException[非法参数异常]" value="java.lang.IllegalArgumentException"> IllegalArgumentException[非法参数异常] </vs-option>
            <vs-option label="ClassCastException[类型转换异常]" value="java.lang.ClassCastException"> ClassCastException[类型转换异常] </vs-option>
            <vs-option label="ArithmeticException[算术异常]" value="java.lang.ArithmeticException"> ArithmeticException[算术异常] </vs-option>
            <vs-option label="NumberFormatException[数字格式化异常]" value="java.lang.NumberFormatException"> NumberFormatException[数字格式化异常] </vs-option>
          </vs-option-group>
          <vs-option-group label="非RuntimeException类">
            <vs-option label="IOException[输入输出异常]" value="java.lang.IOException"> IOException[输入输出异常] </vs-option>
            <vs-option label="SQLException[操作数据库异常]" value="java.lang.SQLException"> SQLException[操作数据库异常] </vs-option>
            <vs-option label="FileNotFoundException[文件未找到异常]" value="java.lang.FileNotFoundException"> FileNotFoundException[文件未找到异常] </vs-option>
            <vs-option label="ClassNotFoundException[类未找到异常]" value="java.lang.ClassNotFoundException"> ClassNotFoundException[类未找到异常] </vs-option>
          </vs-option-group>
          <vs-option-group label="Error类">
            <vs-option label="OutOfMemoryError[内存不足错误]" value="java.lang.OutOfMemoryError"> OutOfMemoryError[内存不足错误] </vs-option>
            <vs-option label="StackOverflowError[堆栈溢出错误]" value="java.lang.StackOverflowError"> StackOverflowError[堆栈溢出错误] </vs-option>
            <vs-option label="NoClassDefFoundError[未找到类定义错误]" value="java.lang.NoClassDefFoundError"> NoClassDefFoundError[未找到类定义错误] </vs-option>
          </vs-option-group>
        </vs-select>

        <!-- <vs-input
          v-model="nodeDataBase.dataName"
          class="w-100 nodrag"
          color="success" 
          label="组件参数名称" 
          label-float 
        />

        <vs-textarea 
          class="w-100 mt-6 nodrag" 
          counter="255" 
          label="组件参数数据" 
          :counter-danger.sync="false" 
          v-model="nodeDataBase.data" 
        />

        <vs-button size="mini" @click="popupDataJson = true">
          JSON编辑器
        </vs-button>

        <vs-dialog v-model="popupDataJson"  not-close auto-width>
          <template #header>
            <h3>组件参数(JSON)</h3>
          </template>
          <div class="con-content-scroll">
            <MonacoEditor
              theme="vs"
              :options="options"
              language="json"
              :width="700"
              :height="500"
              v-model:value="nodeDataBase.data"
            />
          </div>
        </vs-dialog> -->
      </VsCollapseItem>
      <VsCollapseItem >
        <template #header>
          <div>
            样式配置
          </div>
        </template>
        <vs-divider>固定连接点设置</vs-divider>
        <VsRow>
          <VsCol :sm="12" class="ivy-div-center" v-for="(handle,index) in style.handles">
            <vs-checkbox :modelValue="handleOpacity[index]" @update:modelValue="(value) => setHandleOpacity(index, value)">
              {{handle.position == 'left' ? '左' : (handle.position == 'right' ? '右' : (handle.position == 'top' ? '上' : '下'))}}
            </vs-checkbox>
            <vs-radio
              v-model="handle.type"
              value="source"
            >
              source
            </vs-radio>
            <vs-radio
              v-model="handle.type"
              value="target"
            >
              target
            </vs-radio>
            <vs-tooltip placement="right" color="#eee" trigger="click">
              <vs-icon size="30" style="margin-inline-start: 8px;" @click="dialogStyleClick(handle)">
                <vs-icon-SettingBold />
              </vs-icon>
              <template #content> 
                <vs-textarea 
                  width="300px"
                  height="200px"
                  counter="255" 
                  label="【样式格式】bottom: 10px; top: auto;" 
                  v-model="handleStyleText" 
                  :counter-danger.sync="counterDanger"
                  class="w-100 nodrag" 
                />  
              </template>
            </vs-tooltip>
          </VsCol>
          <vs-divider>扩展连接点设置</vs-divider>
          <vs-col :sm="12">
            <vs-button-group style="inline-size: 100%;">
              <vs-tooltip placement="top">
                <vs-button flat style="flex: 1;" @click="addLeftPoint">
                  <vs-icon size="24">
                    <vs-icon-ArrowLeft />
                  </vs-icon>
                </vs-button>
                <template #content> 添加左连接点 </template>
              </vs-tooltip>
              <vs-tooltip placement="top">
                <vs-button flat style="flex: 1;" @click="addRightPoint">
                  <vs-icon size="24">
                    <vs-icon-ArrowRight />
                  </vs-icon>
                </vs-button>
                <template #content> 添加右连接点 </template>
              </vs-tooltip>
              <vs-tooltip placement="top">
                <vs-button flat style="flex: 1;" @click="addTopPoint">
                  <vs-icon size="24">
                    <vs-icon-ArrowUp />
                  </vs-icon>
                </vs-button>
                <template #content> 添加上连接点 </template>
              </vs-tooltip>
              <vs-tooltip placement="top">
                <vs-button flat style="flex: 1;" @click="addBottomPoint">
                  <vs-icon size="24">
                    <vs-icon-ArrowBottom />
                  </vs-icon>
                </vs-button>
                <template #content> 添加下连接点 </template>
              </vs-tooltip>
            </vs-button-group>
          </vs-col>
          <VsCol :sm="12" class="ivy-div-center" v-for="(handle,index) in style.extendHandles">
            <vs-checkbox :modelValue="handleOpacityExtend[index]" @update:modelValue="(value) => setHandleOpacityExtend(index, value)">
              {{handle.position == 'left' ? '左' : (handle.position == 'right' ? '右' : (handle.position == 'top' ? '上' : '下'))}}
            </vs-checkbox>
            <vs-radio
              v-model="handle.type"
              value="source"
            >
              source
            </vs-radio>
            <vs-radio
              v-model="handle.type"
              value="target"
            >
              target
            </vs-radio>
            <vs-tooltip placement="right" color="#eee" trigger="click">
              <vs-icon size="30" style="margin-inline-start: 8px;" @click="dialogStyleClick(handle)">
                <vs-icon-SettingBold />
              </vs-icon>
              <template #content> 
                <vs-textarea 
                  width="300px"
                  height="200px"
                  counter="255" 
                  label="【样式格式】bottom: 10px; top: auto;" 
                  v-model="handleStyleText" 
                  :counter-danger.sync="counterDanger"
                  class="w-100 nodrag" 
                />  
              </template>
            </vs-tooltip>
          </VsCol>
          
        </VsRow>
      </VsCollapseItem>
    </VsCollapse>

    <div>
      <Handle
        v-for="(handle,index) in style.handles"
        :key="index"
        :id="handle.id"
        :class="[
          handle.position == 'left' ? 'handle-node-left' : '', 
          handle.position == 'right' ? 'handle-node-right' : '', 
          handle.position == 'top' ? 'handle-node-top' : '', 
          handle.position == 'bottom' ? 'handle-node-bottom' : '', 
          handle.type == 'source'? 'handle-node-source':'handle-node-target'
        ]"
        :type="handle.type"
        :position="handle.position"
        :style="[handle.style, { opacity: handle.opacity }]"
      >
      </Handle>
    </div>
    <div>
      <Handle
        v-for="(handle,index) in style.extendHandles"
        :key="'extend_'+index"
        :id="handle.id"
        :class="[
          handle.position == 'left' ? 'handle-node-left' : '', 
          handle.position == 'right' ? 'handle-node-right' : '', 
          handle.position == 'top' ? 'handle-node-top' : '', 
          handle.position == 'bottom' ? 'handle-node-bottom' : '', 
          handle.type == 'source'? 'handle-node-source':'handle-node-target'
        ]"
        :type="handle.type"
        :position="handle.position"
        :style="[handle.style, { opacity: handle.opacity }]"
      />
    </div>
  </div>
</template>

<style scoped>
.process-node {
  padding: 5px;
  border-radius: 5px;
  background-color: #fff;
  inline-size: 300px;
  margin-block-end: 0;
}

.process-node-title .icon-with-text{
  border: 0 !important;
  padding-inline: 0;
}
</style>

<style>
.vs-select__option{
  white-space: normal;
  word-break: break-all;
  word-wrap: break-word;
}

.ivy-node-collapse .vs-collapse-item--content .con-content--item .vs-select{
  min-inline-size: 100% !important;
}

.process-node-title .icon-with-text span{
  display: inline-block;
  overflow: hidden;
  font-weight: 600;
  max-inline-size: 80%;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.handle-node-left,.handle-node-right{
  border-radius: 4px !important;
  block-size: 24px !important;
  inline-size: 12px !important; 
}

.handle-node-top,.handle-node-bottom{
  border-radius: 4px !important;
  block-size: 12px !important;
  inline-size: 24px !important; 
}

.handle-node-source{
  background-color: #c8d8fc !important;
}

.handle-node-target{
  background-color: #ff9fa7 !important;
}

.vue-flow__node-toolbar {
  display: flex;
  align-items: center;
  padding: 8px;
  border-radius: 8px;

  /* background-color: #2d3748;
  box-shadow: 0 0 10px rgba(0, 0, 0, 50%); */
  gap: 0.5rem;
}

/* .vue-flow__node-toolbar button {
  border: none;
  border-radius: 8px;
  background: #4a5568;
  color: white;
  cursor: pointer;
  padding-block: 0.5rem;
  padding-inline: 1rem;
}

.vue-flow__node-toolbar button.selected {
  background: #2563eb;
}

.vue-flow__node-toolbar button:hover {
  background: #2563eb;
}

.vue-flow__node-menu {
  border-radius: 8px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 20%);
  padding-block: 16px;
  padding-inline: 24px;
}

.vue-flow__node-menu.selected {
  box-shadow: 0 0 0 2px #2563eb;
} */
</style>
